package com.warm.pump.executor;

import com.warm.pump.module.skd.bean.po.gen.ScheduleInstance;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * 调度任务实例执行器，
 * Created by guozj on 2018/8/28.
 */
@Configuration
@EnableScheduling
@EnableAsync
public class ScheduleExecutor {
    private final Logger logger = LoggerFactory.getLogger(ScheduleExecutor.class);
    @Autowired
    private InstanceService instanceService;
    @Value("${server.port}")
    private Integer port;

    //SpringBoot定时任务默认单线程，多线程需要自行实现或配置文件
    @Scheduled(cron = "0/30 * * * * ?")
    @Async
    public void dealRuningInst() throws InterruptedException {
        //1.获取正在运行且ip、port为第一次执行的ip、port 并且实例任务还未完全完成的实例
        List<Integer> statusList = new ArrayList<>();

        statusList.add(3);
        List<ScheduleInstance> instList = instanceService.getNoCompletedInst(statusList, true);
        if (null == instList) {
            //2.获取正在运行 并且实例任务还未完全完成的实例
            statusList = new ArrayList<>();
            statusList.add(3);
            instList = instanceService.getNoCompletedInst(statusList, false);
            if (null == instList) {
                logger.debug("没有正在运行的任务实例");
                return;
            }
        }

        execInstance(instList);
    }


    /**
     * 处理
     */
    @Scheduled(cron = "25/30 * * * * ?")
    @Async
    public void dealNewInst() {
        List<Integer> statusList = new ArrayList<>();
        //1.获取状态为尚未运行或再运行的实例
        statusList.add(1);
        statusList.add(2);
        List<ScheduleInstance> noCompletedInst = instanceService.getNoCompletedInst(statusList, false);


        if (null == noCompletedInst || noCompletedInst.size() < 1) {
            logger.debug("没有尚未运行或再运行的实例");
            return;
        }

        execInstance(noCompletedInst);

    }


    /**
     * 执行任务实例
     *
     * @param instList
     */
    private void execInstance(List<ScheduleInstance> instList) {
        List<Future> futureList = new ArrayList<>();
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        for (ScheduleInstance inst : instList) {
            Future<?> future = executorService.submit(() -> {
                instanceService.runInstance(inst);
            });
            futureList.add(future);
        }
        //关闭线程池
        executorService.shutdown();
        //通过Future可以并发发出N个请求，然后等待最慢的一个返回
        for (Future future : futureList) {
            try {
                future.get();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
    }
}
